Guest User

Untitled

a guest
May 22nd, 2022
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         Hcaptcha Solver with Browser Trainer(Automatically solves Hcaptcha in browser)
  3. // @namespace    Hcaptcha Solver
  4. // @version      10.1
  5. // @description  Hcaptcha Solver in Browser | Automatically solves Hcaptcha in browser
  6. // @author       Md ubeadulla
  7. // @match        https://*.hcaptcha.com/*hcaptcha-challenge*
  8. // @match        https://*.hcaptcha.com/*checkbox*
  9. // @match        https://*.hcaptcha.com/*captcha*
  10. // @grant        GM_xmlhttpRequest
  11. // @grant        GM_setValue
  12. // @grant        GM_getValue
  13. // @run-at       document-start
  14. // @connect      www.imageidentify.com
  15. // @connect      https://cdnjs.cloudflare.com
  16. // @connect      https://cdn.jsdelivr.net
  17. // @connect      https://unpkg.com
  18. // @connect      https://*.hcaptcha.com/*
  19. // @require      https://unpkg.com/jimp@0.5.2/browser/lib/jimp.min.js
  20. // @require      https://cdnjs.cloudflare.com/ajax/libs/tesseract.js/2.0.0-alpha.2/tesseract.min.js
  21. // @require      https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.13.0/dist/tf.min.js
  22. // @require      https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.2.2/dist/coco-ssd.min.js
  23. // @require      https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@2.1.0/dist/mobilenet.min.js
  24.  
  25. /*
  26. ██╗░░██╗░█████╗░░█████╗░██████╗░████████╗░█████╗░██╗░░██╗░█████╗░  ░██████╗░█████╗░██╗░░░░░██╗░░░██╗███████╗██████╗░
  27. ██║░░██║██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗██║░░██║██╔══██╗  ██╔════╝██╔══██╗██║░░░░░██║░░░██║██╔════╝██╔══██╗
  28. ███████║██║░░╚═╝███████║██████╔╝░░░██║░░░██║░░╚═╝███████║███████║  ╚█████╗░██║░░██║██║░░░░░╚██╗░██╔╝█████╗░░██████╔╝
  29. ██╔══██║██║░░██╗██╔══██║██╔═══╝░░░░██║░░░██║░░██╗██╔══██║██╔══██║  ░╚═══██╗██║░░██║██║░░░░░░╚████╔╝░██╔══╝░░██╔══██╗
  30. ██║░░██║╚█████╔╝██║░░██║██║░░░░░░░░██║░░░╚█████╔╝██║░░██║██║░░██║  ██████╔╝╚█████╔╝███████╗░░╚██╔╝░░███████╗██║░░██║
  31. ╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝╚═╝░░░░░░░░╚═╝░░░░╚════╝░╚═╝░░╚═╝╚═╝░░╚═╝  ╚═════╝░░╚════╝░╚══════╝░░░╚═╝░░░╚══════╝╚═╝░░╚═╝
  32. */
  33. /** Note: This script is solely intended for the use of educational purposes only and not to abuse any website.
  34.  * Sign Up using the referral links or consider a donation to the following addresses:
  35.  ***************************************************************************************************
  36.  * Faucets:                                                                                        *
  37.  * Install the free cryporotator https://greasyfork.org/en/scripts/426599-free-cryptorotator       *
  38.  * Or Sign up using the referral link and solve captchas to earn crypto (Do not abuse the websites)*
  39.  * 1.) https://get-bitcoin.net/?ref=9230                                                           *
  40.  * 2.) https://getdoge.io/?ref=34017                                                               *
  41.  * 3.) https://r.adbtc.top/1771513                   *
  42.  * 4.) https://cryptowin.io/ref/ubeadulla                                                          *
  43.  * 5.) https://winalittle.fun/referral/02c7061877cec89e81a306303d36b77c                            *
  44.  * 6.) https://faucetofbob.xyz/?ref=2121                                                           *
  45.  * 7.) https://free-litecoin.com/login?referer=1035367                                             *
  46.  * 8.) https://free-ethereum.io/?referer=742436                                                    *
  47.  * 9.) https://litking.biz/signup?r=125431                                                         *
  48.  * 10.) https://bitking.biz/signup?r=75339                                                         *
  49.  ***************************************************************************************************
  50.  * MicroWallets:                                                                                   *
  51.  * 1.) FaucetPay: BTC: 1HeD2a11n8d9zBTaznNWfVxtw1dKuW2vT5                                          *
  52.  *     LTC: MHpCuD3zAFEkeuhbgLbuZKcfdqMFkaLSem                                                     *
  53.  *     BCH: bitcoincash:qp7ywra8h7lwatcuc7u65lv8x6rv5kn4sutrsnzrpx                                 *
  54.  *     TRX: TLs3iQfXJs1rmUuG6pkLkUwcu32mFUwzgu                                                     *
  55.  *     Doge: DPtBQG9GNTYHUFkjB2zYWYah4nCCogVAt9                                                    *                                             *
  56.  * 2.) Direct BTC: 35HbfGfvbdctzY6tT4jcHXRx4zonBTnDuC                                              *
  57.  ***************************************************************************************************
  58.  * Cloud Mining Websites Just SignUp and earn passive income                                       *                                                                                       *
  59.  * 1.) https://tronrex.online/r/86733                                                              *
  60.  *                                                     *
  61.  ***************************************************************************************************
  62.  */
  63.  
  64. // ==/UserScript==
  65. (async function() {
  66.  
  67.     //TODO: Enable debug mode to print console logs
  68.     //TODO: Refactor Code for different models
  69.     'use strict';
  70.     var selectedImageCount = 0;
  71.     var tensorFlowModel = undefined;
  72.     var tensorFlowMobileNetModel = undefined;
  73.     var worker = undefined;
  74.  
  75.     var identifiedObjectsList = [];
  76.     var exampleImageList = [];
  77.     var identifyObjectsFromImagesCompleted = false;
  78.     var currentExampleUrls = [];
  79.  
  80.     //Default Language for hcaptcha
  81.     const LANG_ENGLISH = "English"
  82.     const DEFAULT_LANGUAGE = LANG_ENGLISH;
  83.     const ENABLE_DEFAULT_LANGUAGE = true;
  84.  
  85.     //Guess/Match New Images
  86.     const MATCH_IMAGES_USING_TRAINER = false;
  87.     const GUESS_NEW_IMAGE_TYPE = false;
  88.  
  89.     //Node Selectors
  90.     const CHECK_BOX = "#checkbox";
  91.     const SUBMIT_BUTTON = ".button-submit";
  92.     const TASK_IMAGE_BORDER = ".task-image .border";
  93.     const IMAGE = ".task-image .image";
  94.     const TASK_IMAGE = ".task-image";
  95.     const PROMPT_TEXT = ".prompt-text";
  96.     const NO_SELECTION = ".no-selection";
  97.     const CHALLENGE_INPUT_FIELD = ".challenge-input .input-field";
  98.     const CHALLENGE_INPUT = ".challenge-input";
  99.     const CHALLENGE_IMAGE = ".challenge-example .image .image";
  100.     const IMAGE_FOR_OCR = ".challenge-image .zoom-image";
  101.     const LANGUAGE_SELECTOR = "#language-list .scroll-container .option span";
  102.  
  103.     //Attributes
  104.     const ARIA_CHECKED = "aria-checked";
  105.     const ARIA_HIDDEN = "aria-hidden";
  106.  
  107.     //Values that can be changed for other languages
  108.     const AIRPLANE = "airplane";
  109.     const BICYCLE = "bicycle";
  110.     const BOAT = "boat";
  111.     const BUS = "bus";
  112.     const CAR = "car";
  113.     const MOTORBUS = "motorbus";
  114.     const MOTORCYCLE = "motorcycle";
  115.     const SURFBOARD = "surfboard";
  116.     const TRAIN = "train";
  117.     const TRUCK = "truck";
  118.     const TRIMARAN = "trimaran";
  119.     const SEAPLANE = "seaplane";
  120.     const SPEEDBOAT = "speedboat";
  121.  
  122.     //Living Room Objects
  123.     const BED = "bed";
  124.     const BOOK = "book";
  125.     const CHAIR = "chair";
  126.     const CLOCK = "clock";
  127.     const COUCH = "couch";
  128.     const DINING_TABLE = "dining table";
  129.     const POTTED_PLANT = "potted plant";
  130.     const TV = "tv";
  131.  
  132.     //Animals
  133.     const ZEBRA = "zebra";
  134.     const CAT = "cat";
  135.     const DOG = "dog";
  136.  
  137.     // Vertical River
  138.     const VALLEY = "valley";
  139.     const VERTICAL_RIVER = "vertical river";
  140.  
  141.  
  142.     const LIVING_ROOM_TYPES = [BED, BOOK, CHAIR, CLOCK, COUCH, DINING_TABLE, POTTED_PLANT, TV];
  143.     const TRANSPORT_TYPES = [AIRPLANE, BICYCLE, BOAT, BUS, CAR, MOTORBUS, MOTORCYCLE, SEAPLANE, SPEEDBOAT, SURFBOARD, TRAIN, TRIMARAN, TRUCK];
  144.     const ANIMAL_TYPES = [ZEBRA, CAT, DOG];
  145.  
  146.     const SENTENCE_TEXT_A = "Please click each image containing a ";
  147.     const SENTENCE_TEXT_AN = "Please click each image containing an ";
  148.     const LANGUAGE_FOR_OCR = "eng";
  149.  
  150.     // Option to override the default image matching
  151.     // Enabling this by default
  152.     const ENABLE_TENSORFLOW = true;
  153.  
  154.     // Max Skips that can be done while solving the captcha
  155.     // This is likely not to happen, if it occurs retry for new images
  156.     const MAX_SKIPS = 10;
  157.     var skipCount = 0;
  158.  
  159.     var USE_MOBILE_NET = false;
  160.     var USE_COLOUR_PATTERN = false;
  161.     var NEW_WORD_IDENTIFIED = false;
  162.  
  163.     //Probablility for objects
  164.     var probabilityForObject = new Map();
  165.     probabilityForObject.set("speedboat", 0.14);
  166.     probabilityForObject.set("fireboat", 0.4);
  167.     probabilityForObject.set("boathouse", 0.4);
  168.     probabilityForObject.set("submarine", 0.5);
  169.     probabilityForObject.set("printer", 0.05);
  170.     probabilityForObject.set("stretcher", 0.05);
  171.     probabilityForObject.set("rotisserie", 0.02);
  172.     probabilityForObject.set("spatula", 0.05);
  173.  
  174.  
  175.     String.prototype.includesOneOf = function(arrayOfStrings) {
  176.  
  177.         //If this is not an Array, compare it as a String
  178.         if (!Array.isArray(arrayOfStrings)) {
  179.             return this.toLowerCase().includes(arrayOfStrings.toLowerCase());
  180.         }
  181.  
  182.         for (var i = 0; i < arrayOfStrings.length; i++) {
  183.             if ((arrayOfStrings[i].substr(0, 1) == "=" && this.toLowerCase() == arrayOfStrings[i].substr(1).toLowerCase()) ||
  184.                 (this.toLowerCase().includes(arrayOfStrings[i].toLowerCase()))) {
  185.                 return true;
  186.             }
  187.         }
  188.         return false;
  189.     }
  190.  
  191.     String.prototype.equalsOneOf = function(arrayOfStrings) {
  192.  
  193.         //If this is not an Array, compare it as a String
  194.         if (!Array.isArray(arrayOfStrings)) {
  195.             return this.toLowerCase() == arrayOfStrings.toLowerCase();
  196.         }
  197.  
  198.         for (var i = 0; i < arrayOfStrings.length; i++) {
  199.             if ((arrayOfStrings[i].substr(0, 1) == "=" && this.toLowerCase() == arrayOfStrings[i].substr(1).toLowerCase()) ||
  200.                 (this.toLowerCase() == arrayOfStrings[i].toLowerCase())) {
  201.                 return true;
  202.             }
  203.         }
  204.         return false;
  205.     }
  206.  
  207.  
  208.  
  209.     // This script uses imageidentify API (wolfram) . You may also use TensorFlow.js, Yolo latest version to recognize common objects.
  210.     //(When the cloud service is available for yolo, we can switch the API endpoint). Accuracy varies between Wolfram, Tensorflow and Yolo.
  211.     // Use this as a reference to solve recaptcha/other captchas using scripts in browser. This is intended for learning purposes.
  212.     // Using TensorFlow as fallback, but this requires good CPU in order to solve quickly.
  213.     // CPU utilization and memory utlization may go high when using TensorFlow.js
  214.     function matchImages(imageUrl, word, i) {
  215.  
  216.         GM_xmlhttpRequest({
  217.             method: "POST",
  218.             url: "https://www.imageidentify.com/objects/user-26a7681f-4b48-4f71-8f9f-93030898d70d/prd/urlapi/",
  219.             headers: {
  220.                 "Content-Type": "application/x-www-form-urlencoded"
  221.             },
  222.             data: "image=" + encodeURIComponent(imageUrl),
  223.             timeout: 8000,
  224.             onload: function(response) {
  225.                 clickImages(response, imageUrl, word, i)
  226.             },
  227.             onerror: function(e) {
  228.                 //Using Fallback TensorFlow
  229.                 if (e && e.status && e.status != 0) {
  230.                     console.log(e);
  231.                     console.log("Using Fallback");
  232.                 }
  233.                 matchImagesUsingTensorFlow(imageUrl, word, i);
  234.  
  235.             },
  236.             ontimeout: function() {
  237.                 //console.log("Timed out. Using Fallback");
  238.                 matchImagesUsingTensorFlow(imageUrl, word, i);
  239.             },
  240.         });
  241.  
  242.     }
  243.  
  244.     function matchImagesUsingTensorFlow(imageUrl, word, i) {
  245.         try {
  246.             let img = new Image();
  247.             img.crossOrigin = "Anonymous";
  248.             img.src = imageUrl;
  249.             img.onload = () => {
  250.                 initializeTensorFlowModel().then(model => model.detect(img))
  251.                     .then(function(predictions) {
  252.                     var predictionslen = predictions.length;
  253.                     for (var j = 0; j < predictionslen; j++) {
  254.                         if (qSelectorAll(IMAGE)[i] && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  255.                             qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 0 &&
  256.                             predictions[j].class.includesOneOf(word)) {
  257.                             qSelectorAll(TASK_IMAGE)[i].click();
  258.                             break;
  259.                         }
  260.                     }
  261.                     img.removeAttribute("src");
  262.                     selectedImageCount = selectedImageCount + 1;
  263.                 });
  264.             }
  265.         } catch (err) {
  266.             console.log(err.message);
  267.         }
  268.     }
  269.  
  270.  
  271.     function matchImagesUsingTensorFlowMobileNet(imageUrl, word, i) {
  272.  
  273.         try {
  274.             let img = new Image();
  275.             img.crossOrigin = "Anonymous";
  276.             img.src = imageUrl;
  277.             img.onload = () => {
  278.                 initializeTensorFlowMobilenetModel().then(model => model.classify(img))
  279.                     .then(function(predictions) {
  280.                     var predictionslen = predictions.length;
  281.                     for (var j = 0; j < predictionslen; j++) {
  282.                         var probability = 0.077;
  283.                         if (probabilityForObject.get(predictions[j].className)) {
  284.                             probability = probabilityForObject.get(predictions[j].className);
  285.                         }
  286.  
  287.                         if (qSelectorAll(IMAGE)[i] && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  288.                             qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 0 &&
  289.                             predictions[j].className.includesOneOf(word) && predictions[j].probability > probability) {
  290.                             qSelectorAll(TASK_IMAGE)[i].click();
  291.                             break;
  292.                         }
  293.                     }
  294.                     img.removeAttribute("src");
  295.                     selectedImageCount = selectedImageCount + 1;
  296.                 });
  297.             }
  298.         } catch (err) {
  299.             console.log(err.message);
  300.         }
  301.     }
  302.  
  303.  
  304.     // TODO: Generalize this logic
  305.     // Identifying this based on the observation of the images seen
  306.     // The actual way would be to scan the entire image to find the lake.
  307.     // Mobilenet model in browser js identifies the lake but does not provide coordinates
  308.     // to identify if it is horizontal or vertical
  309.     function matchImageForVerticalRiver(imageUrl, word, i) {
  310.  
  311.         Jimp.read(imageUrl).then(function (data) {
  312.  
  313.             data.getBase64(Jimp.AUTO, async function (err, src) {
  314.                 var img = document.createElement("img");
  315.                 img.setAttribute("src", src);
  316.                 await img.decode();
  317.                 var imageHeight = img.height;
  318.                 var imageWidth = img.width;
  319.                 var cropHeight = imageHeight - 0.03*imageHeight;
  320.                 let url = src.replace(/^data:image\/\w+;base64,/, "");
  321.                 let buffer = new Buffer(url, 'base64');
  322.  
  323.                 Jimp.read(buffer).then(function (data) {
  324.                     data.crop(0, cropHeight, imageWidth, imageHeight)
  325.                         .getBase64(Jimp.AUTO, async function (err, src) {
  326.  
  327.                         var img = document.createElement("img");
  328.                         img.src = src;
  329.                         await img.decode();
  330.  
  331.                         var c = document.createElement("canvas")
  332.                         c.width = img.width;
  333.                         c.height = img.height;
  334.                         var ctx = c.getContext("2d");
  335.                         ctx.drawImage(img, 0, 0);
  336.  
  337.                         var imageData = ctx.getImageData(0, 0, c.width, c.height);
  338.                         var data = imageData.data;
  339.                         var count = 0;
  340.  
  341.                         //Multiple combinations and distances are required for accuracy
  342.                         for (let i = 0; i < data.length; i+= 4) {
  343.                             if( (data[i] < 140 && data[i+1] < 110 && data[i+2] > 80 && data[i+3] == 255) ||
  344.                                (data[i] < 200 && data[i+1] < 200 && data[i+2] > 140 && data[i+3] == 255)){
  345.                                 count++;
  346.                             }
  347.                         }
  348.  
  349.                         if(count > 0.001*(data.length/4) && count < data.length/8) {
  350.                             if (qSelectorAll(IMAGE)[i] && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  351.                                 qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 0) {
  352.                                 qSelectorAll(TASK_IMAGE)[i].click();
  353.                             }
  354.                         }
  355.  
  356.                         img.removeAttribute("src");
  357.                         selectedImageCount = selectedImageCount + 1;
  358.  
  359.                     });
  360.                 });
  361.                 img.removeAttribute("src");
  362.             });
  363.         });
  364.     }
  365.  
  366.  
  367.     // This approach is naive approch to store the images and retrieve
  368.     // The accuracy is 100% as long as you store the selected images
  369.     // Browser memory is used to store the images and gets cleared if you delete the browser cache and cookies
  370.     // You may use this to store images in remote place and retrive for quick access
  371.     // This approach is only used during urgent scenarios before training the images
  372.     // Image differnce can also be done with the stored images to identify new image based on the existing if they are nearly equal
  373.     function matchImagesUsingTrainer(imageUrl, word, i) {
  374.  
  375.         Jimp.read(imageUrl).then(function (data) {
  376.  
  377.             data.getBase64(Jimp.AUTO, async function (err, src) {
  378.                 var trainerInterval = setInterval(function(){
  379.  
  380.                     if (!qSelectorAll(IMAGE)[i] || !(qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) ){
  381.                         clearInterval(trainerInterval);
  382.                         return;
  383.                     }
  384.  
  385.                     if (qSelectorAll(IMAGE)[i] && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  386.                         qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 0 && GM_getValue(src) && GM_getValue(src) == word) {
  387.                         console.log("Retrieved image from trainer");
  388.                         selectedImageCount = selectedImageCount + 1;
  389.                         qSelectorAll(TASK_IMAGE)[i].click();
  390.                         clearInterval(trainerInterval);
  391.                         return;
  392.                     }
  393.  
  394.                     // Overriding Previously Stored values
  395.                     if (qSelectorAll(IMAGE)[i] && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  396.                         qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 1 && GM_getValue(src) && GM_getValue(src) != word) {
  397.                         console.log("Overriding image in the trainer");
  398.                         selectedImageCount = selectedImageCount + 1;
  399.                         GM_setValue(src,word);
  400.                         console.log("Image Stored into database");
  401.                         clearInterval(trainerInterval);
  402.                         return;
  403.                     }
  404.  
  405.                     if (qSelectorAll(IMAGE)[i] && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  406.                         qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 1 && !GM_getValue(src)) {
  407.                         selectedImageCount = selectedImageCount + 1;
  408.                         GM_setValue(src,word);
  409.                         console.log("Image Stored into database");
  410.                         clearInterval(trainerInterval);
  411.                         return;
  412.  
  413.                     }
  414.  
  415.                 },5000);
  416.  
  417.             });
  418.         });
  419.     }
  420.  
  421.  
  422.     //Function to sleep or delay
  423.     async function delay(ms) {
  424.         return new Promise(resolve => setTimeout(resolve, ms))
  425.     }
  426.  
  427.     //Different Models can be set later based on usecase
  428.     //Ref Models: https://github.com/tensorflow/tfjs-models
  429.     async function initializeTensorFlowModel() {
  430.         if (!tensorFlowModel) {
  431.             tensorFlowModel = await cocoSsd.load();
  432.         }
  433.         return tensorFlowModel;
  434.     }
  435.  
  436.     //MobileNet ssd model
  437.     async function initializeTensorFlowMobilenetModel() {
  438.         if (!tensorFlowMobileNetModel) {
  439.             tensorFlowMobileNetModel = await mobilenet.load();
  440.         }
  441.         return tensorFlowMobileNetModel;
  442.     }
  443.  
  444.  
  445.     //Initialize TesseractWorker
  446.     function initializeTesseractWorker() {
  447.         if (!worker) {
  448.             worker = new Tesseract.TesseractWorker();
  449.         }
  450.     }
  451.  
  452.     function clickImages(response, imageUrl, word, i) {
  453.  
  454.         try {
  455.             if (response && response.responseText && (qSelectorAll(IMAGE)[i].style.background).includes(imageUrl) &&
  456.                 qSelectorAll(TASK_IMAGE_BORDER)[i].style.opacity == 0) {
  457.                 var responseJson = JSON.parse(response.responseText);
  458.                 if (responseJson.identify && responseJson.identify.title && responseJson.identify.title.includesOneOf(word)) {
  459.                     qSelectorAll(TASK_IMAGE)[i].click();
  460.                 } else if (responseJson.identify && responseJson.identify.entity && responseJson.identify.entity.includesOneOf(word)) {
  461.                     qSelectorAll(TASK_IMAGE)[i].click();
  462.                 } else if (responseJson.identify && responseJson.identify.alternatives) {
  463.                     var alternatives = JSON.stringify(responseJson.identify.alternatives);
  464.                     var alternativesJson = JSON.parse(alternatives);
  465.  
  466.                     for (var key in alternativesJson) {
  467.                         if (alternativesJson.hasOwnProperty(key)) {
  468.                             if ((alternativesJson[key].includesOneOf(word) || key.includesOneOf(word))) {
  469.                                 qSelectorAll(TASK_IMAGE)[i].click();
  470.                                 break;
  471.                             }
  472.                         }
  473.                     }
  474.                 } else {
  475.                     //No Match found
  476.                 }
  477.  
  478.                 selectedImageCount = selectedImageCount + 1;
  479.  
  480.             } else {
  481.                 //console.log("Using Fallback TensorFlow");
  482.                 matchImagesUsingTensorFlow(imageUrl, word, i);
  483.             }
  484.  
  485.         } catch (err) {
  486.             //Using Fallback TensorFlow
  487.             //console.log(err.message);
  488.             //console.log("Using Fallback TensorFlow");
  489.             matchImagesUsingTensorFlow(imageUrl, word, i);
  490.         }
  491.     }
  492.  
  493.     function qSelectorAll(selector) {
  494.         return document.querySelectorAll(selector);
  495.     }
  496.  
  497.     function qSelector(selector) {
  498.         return document.querySelector(selector);
  499.     }
  500.  
  501.  
  502.     async function getSynonyms(word) {
  503.  
  504.         USE_MOBILE_NET = false;
  505.         USE_COLOUR_PATTERN = false;
  506.         NEW_WORD_IDENTIFIED = false;
  507.  
  508.         //TODO: Format this to JSON string
  509.         if (word == MOTORBUS || word == BUS) {
  510.             word = ['bus', 'motorbus'];
  511.             USE_MOBILE_NET = true;
  512.         } else if (word == CAR) {
  513.             word = ['=car', 'coupe', 'jeep', 'limo', 'sport utility vehicle', 'station wagon', 'hatchback', 'bumper car', 'modelT', 'electric battery', 'cruiser'];
  514.             USE_MOBILE_NET = true;
  515.         } else if (word == AIRPLANE) {
  516.             word = ['airplane', 'plane', 'aircraft', 'aeroplane', 'hangar', 'Airdock', 'JumboJet', 'jetliner', 'stealth fighter', 'field artillery']
  517.             USE_MOBILE_NET = true;
  518.         } else if (word == TRAIN) {
  519.             word = ['train', 'rail', 'cable car', 'locomotive', 'subway station']
  520.             USE_MOBILE_NET = true;
  521.         } else if (word == BOAT || word == SURFBOARD) {
  522.             word = ['=boat', '=barge', 'houseboat', 'boathouse', 'speedboat', '=submarine', 'bobsled', 'catamaran', 'schooner', 'ocean liner', 'lifeboat', 'fireboat', 'yawl', 'pontoon', 'small boat', 'SnowBlower', 'Sea-coast', 'paddlewheel', 'paddle wheel', 'PaddleSteamer', 'Freighter', 'Sternwheeler', 'kayak', 'canoe', 'deck', 'DockingFacility', 'surfboard', '=ship', '=cruise', 'watercraft', 'sail', 'canvas', '=raft']
  523.             USE_MOBILE_NET = true;
  524.         } else if (word == BICYCLE) {
  525.             word = ['bicycle-built-for-two', 'tandem bicycle', 'bicycle', 'tricycle', 'mountain bike', 'AcceleratorPedal', 'macaw', 'knot']
  526.             USE_MOBILE_NET = true;
  527.         } else if (word == MOTORCYCLE) {
  528.             word = ['moped', 'motor scooter', 'scooter', 'motorcycle', 'windshield', 'dashboard']
  529.             USE_MOBILE_NET = true;
  530.         } else if (word == TRUCK) {
  531.             word = ['truck', 'cargocontainer', 'bazooka']
  532.             USE_MOBILE_NET = true;
  533.         } else if (word == TRIMARAN || word == SPEEDBOAT || word == SEAPLANE) {
  534.             word = ['spatula', 'can opener', 'tin opener', 'monitor', 'screen', 'stretcher', 'printer', 'nail', 'mousetrap', 'TRIMARAN', 'space shuttle', 'ski', 'rotisserie', 'geyser', 'plate rack']
  535.             USE_MOBILE_NET = true;
  536.         } else if (word.includesOneOf(LIVING_ROOM_TYPES)) {
  537.             word = ['bed', 'couch', 'chair', 'potted plant', 'dining table', 'clock', 'tv', 'book']
  538.         } else if (word == ZEBRA) {
  539.             word = ['zebra']
  540.         } else if (word == CAT) {
  541.             word = ['cat']
  542.             USE_MOBILE_NET = true;
  543.         } else if (word == DOG) {
  544.             word = ['dog']
  545.         } else if (word == VALLEY || word == VERTICAL_RIVER){
  546.             word = ['alp','volcano']
  547.             USE_COLOUR_PATTERN = true;
  548.         } else {
  549.             NEW_WORD_IDENTIFIED = true;
  550.             console.log("Word does not match. New type identified::" + word);
  551.         }
  552.  
  553.         return word
  554.  
  555.     }
  556.  
  557.     function isHidden(el) {
  558.         return (el.offsetParent === null)
  559.     }
  560.  
  561.     if (window.location.href.includes("checkbox")) {
  562.         var checkboxInterval = setInterval(function() {
  563.             if (!qSelector(CHECK_BOX)) {
  564.                 //Wait until the checkbox element is visible
  565.             } else if (qSelector(CHECK_BOX).getAttribute(ARIA_CHECKED) == "true") {
  566.                 clearInterval(checkboxInterval);
  567.             } else if (!isHidden(qSelector(CHECK_BOX)) && qSelector(CHECK_BOX).getAttribute(ARIA_CHECKED) == "false") {
  568.                 qSelector(CHECK_BOX).click();
  569.             } else {
  570.                 return;
  571.             }
  572.  
  573.         }, 5000);
  574.     } else {
  575.  
  576.         try {
  577.             selectImages();
  578.  
  579.         } catch (err) {
  580.             console.log(err);
  581.             console.log("Tesseract could not be initialized");
  582.         }
  583.  
  584.     }
  585.  
  586.     function selectImagesAfterDelay(delay) {
  587.         setTimeout(function() {
  588.             selectImages();
  589.         }, delay * 1000);
  590.     }
  591.  
  592.     function triggerEvent(el, type) {
  593.         var e = document.createEvent('HTMLEvents');
  594.         e.initEvent(type, false, true);
  595.         el.dispatchEvent(e);
  596.     }
  597.  
  598.     function triggerMouseEvent(el, type) {
  599.         var e = document.createEvent('MouseEvent');
  600.         e.initEvent(type, false, true);
  601.         el.dispatchEvent(e);
  602.     }
  603.  
  604.     // Small hack to select the nodes
  605.     function unsure(targetNodeText) {
  606.         var targetNode = Array.from(qSelectorAll('div'))
  607.         .find(el => el.textContent === targetNodeText);
  608.         //Works for now
  609.         //TODO: Select clothing
  610.         //TODO: Draw boxes around images
  611.         if (targetNode) {
  612.             triggerMouseEvent(targetNode, 'mousedown');
  613.             triggerMouseEvent(targetNode, 'mouseup');
  614.             if (qSelector(SUBMIT_BUTTON)) {
  615.                 qSelector(SUBMIT_BUTTON).click();
  616.             }
  617.         }
  618.         return selectImagesAfterDelay(1);
  619.     }
  620.  
  621.     function getUrlFromString(urlString) {
  622.  
  623.         var imageUrl = urlString.substring(
  624.             urlString.indexOf('"') + 1,
  625.             urlString.lastIndexOf('"')
  626.         );
  627.  
  628.         if (!imageUrl || !imageUrl.includes("https")) {
  629.             return 0;
  630.         }
  631.  
  632.         return imageUrl;
  633.     }
  634.  
  635.  
  636.     function getImageList() {
  637.         var imageList = [];
  638.         if (qSelectorAll(IMAGE).length > 0) {
  639.             for (var i = 0; i < 9; i++) {
  640.                 var urlString = qSelectorAll(IMAGE)[i].style.background;
  641.                 var imageUrl = getUrlFromString(urlString);
  642.                 if (imageUrl == 0) {
  643.                     //console.log("Image url is empty");
  644.                     return imageList;
  645.                 }
  646.                 imageList[i] = imageUrl;
  647.             }
  648.         }
  649.         return imageList;
  650.     }
  651.  
  652.     function waitUntilImageSelection() {
  653.         var imageIntervalCount = 0;
  654.         var imageInterval = setInterval(function() {
  655.             imageIntervalCount = imageIntervalCount + 1;
  656.             if (selectedImageCount == 9) {
  657.                 clearInterval(imageInterval);
  658.                 if (qSelector(SUBMIT_BUTTON)) {
  659.                     qSelector(SUBMIT_BUTTON).click();
  660.                 }
  661.                 return selectImagesAfterDelay(5);
  662.             } else if (imageIntervalCount > 8) {
  663.                 clearInterval(imageInterval);
  664.                 return selectImages();
  665.             } else if(selectedImageCount > 2 && MATCH_IMAGES_USING_TRAINER && NEW_WORD_IDENTIFIED && imageIntervalCount > 4){
  666.                 clearInterval(imageInterval);
  667.                 if (qSelector(SUBMIT_BUTTON)) {
  668.                     qSelector(SUBMIT_BUTTON).click();
  669.                 }
  670.                 return selectImagesAfterDelay(5);
  671.             } else if(MATCH_IMAGES_USING_TRAINER && NEW_WORD_IDENTIFIED && imageIntervalCount > 6){
  672.                 clearInterval(imageInterval);
  673.                 if (qSelector(SUBMIT_BUTTON)) {
  674.                     qSelector(SUBMIT_BUTTON).click();
  675.                 }
  676.                 return selectImagesAfterDelay(5);
  677.             }else{
  678.  
  679.             }
  680.         }, 3000);
  681.     }
  682.  
  683.     function waitForImagesToAppear() {
  684.         var checkImagesSelectedCount = 0;
  685.         var waitForImagesInterval = setInterval(function() {
  686.             checkImagesSelectedCount = checkImagesSelectedCount + 1;
  687.             if (qSelectorAll(IMAGE) && qSelectorAll(IMAGE).length == 9) {
  688.                 clearInterval(waitForImagesInterval);
  689.                 return selectImages();
  690.             } else if (checkImagesSelectedCount > 60) {
  691.                 clearInterval(waitForImagesInterval);
  692.             } else if (qSelector(CHALLENGE_INPUT_FIELD) && qSelector(NO_SELECTION).getAttribute(ARIA_HIDDEN) != true) {
  693.                 clearInterval(waitForImagesInterval);
  694.                 return imageUsingOCR();
  695.             } else {
  696.                 //TODO: Identify Objects for the following (Ex: bed,chair,table etc)
  697.                 //Ref for clothing: https://www.youtube.com/watch?v=yWwzFnAnrLM, https://www.youtube.com/watch?v=FiNglI1wRNk,https://www.youtube.com/watch?v=oHAkK_9UCQ8
  698.                 var targetNodeList = ["Yes", "3 or more items of furniture", "Equipped space or room", "Photo is clean, no watermarks, logos or text overlays", "An interior photo of room", "Unsure", "Photo is sharp"];
  699.                 for (var j = 0; j < targetNodeList.length; j++) {
  700.                     var targetNode = Array.from(qSelectorAll('div'))
  701.                     .find(el => el.textContent === targetNodeList[j]);
  702.                     if (targetNode) {
  703.                         //console.log("Target Node Found");
  704.                         clearInterval(waitForImagesInterval);
  705.                         return unsure(targetNodeList[j]);
  706.                     }
  707.                 }
  708.             }
  709.         }, 5000);
  710.     }
  711.  
  712.     //TODO: Convert Image to base64 to avoid multiple calls
  713.     function preProcessImage(base64Image, imageUrl) {
  714.  
  715.         //Darken and Brighten
  716.         Jimp.read(base64Image).then(function(data) {
  717.             data.color([
  718.  
  719.                 {
  720.                     apply: 'darken',
  721.                     params: [20]
  722.                 }
  723.  
  724.             ]).color([
  725.  
  726.                 {
  727.                     apply: 'brighten',
  728.                     params: [20]
  729.                 }
  730.  
  731.             ])
  732.                 .greyscale()
  733.                 .getBase64(Jimp.AUTO, function(err, src) {
  734.                 var img = document.createElement("img");
  735.                 img.setAttribute("src", src);
  736.  
  737.                 worker.recognize(img, LANGUAGE_FOR_OCR).then(function(data) {
  738.                     //Remove Image After recognizing
  739.                     img.removeAttribute("src");
  740.                     //If null change to other methods
  741.                     if (data && data.text && data.text.length > 0) {
  742.                         inputChallenge(postProcessImage(data), imageUrl);
  743.                         return selectImages();
  744.                     } else {
  745.                         preProcessImageMethod2(base64Image, imageUrl);
  746.                     }
  747.                 });
  748.  
  749.             });
  750.         });
  751.  
  752.     }
  753.  
  754.  
  755.     function preProcessImageMethod2(base64Image, trimageUrl) {
  756.  
  757.         //Multi Contrast darken and brighten
  758.         Jimp.read(base64Image).then(function(data) {
  759.             data.color([
  760.  
  761.                 {
  762.                     apply: 'darken',
  763.                     params: [20]
  764.                 }
  765.  
  766.             ]).contrast(1).color([
  767.  
  768.                 {
  769.                     apply: 'brighten',
  770.                     params: [20]
  771.                 }
  772.  
  773.             ]).contrast(1).greyscale().getBase64(Jimp.AUTO, function(err, src) {
  774.                 var img = document.createElement("img");
  775.                 img.setAttribute("src", src);
  776.  
  777.                 worker.recognize(img, LANGUAGE_FOR_OCR).then(function(data) {
  778.                     //Remove Image After recognizing
  779.                     img.removeAttribute("src");
  780.                     if (data && data.text && data.text.length > 0) {
  781.                         inputChallenge(postProcessImage(data), imageUrl);
  782.                         return selectImages();
  783.                     } else {
  784.                         preProcessImageMethod3(base64Image, imageUrl);
  785.                     }
  786.                 });
  787.             });
  788.         });
  789.  
  790.     }
  791.  
  792.     function preProcessImageMethod3(base64Image, imageUrl) {
  793.         //Multi Contrast only brighten
  794.         Jimp.read(base64Image).then(function(data) {
  795.             data.contrast(1).color([{
  796.                 apply: 'brighten',
  797.                 params: [20]
  798.             }
  799.  
  800.                                    ])
  801.                 .contrast(1)
  802.                 .greyscale()
  803.                 .getBase64(Jimp.AUTO, function(err, src) {
  804.                 var img = document.createElement("img");
  805.                 img.setAttribute("src", src);
  806.  
  807.                 worker.recognize(img, LANGUAGE_FOR_OCR).then(function(data) {
  808.                     //Remove Image After recognizing
  809.                     img.removeAttribute("src");
  810.                     if (data && data.text && data.text.length > 0) {
  811.                         inputChallenge(postProcessImage(data), imageUrl);
  812.                         return selectImages();
  813.                     } else {
  814.                         preProcessImageMethod4(base64Image, imageUrl);
  815.                     }
  816.                 });
  817.             });
  818.         });
  819.     }
  820.  
  821.     function preProcessImageMethod4(base64Image, imageUrl) {
  822.         //Resize the image
  823.         Jimp.read(base64Image).then(function(data) {
  824.             data.resize(256, Jimp.AUTO)
  825.                 .quality(60) // set JPEG quality
  826.                 .greyscale() // set greyscale
  827.                 .getBase64(Jimp.AUTO, function(err, src) {
  828.                 var img = document.createElement("img");
  829.                 img.setAttribute("src", src);
  830.  
  831.                 worker.recognize(img, LANGUAGE_FOR_OCR).then(function(data) {
  832.                     //Remove Image After recognizing
  833.                     img.removeAttribute("src");
  834.                     inputChallenge(postProcessImage(data), imageUrl);
  835.                     return selectImages();
  836.                 });
  837.             });
  838.         });
  839.  
  840.     }
  841.  
  842.     function postProcessImage(data) {
  843.         var filterValues = ['\n', '{', '}', '[', ']'];
  844.         for (var i = 0; i < filterValues.length; i++) {
  845.             data.text = data.text.replaceAll(filterValues[i], "");
  846.         }
  847.         return data;
  848.     }
  849.  
  850.     // Using Tesseract to recognize images
  851.     function imageUsingOCR() {
  852.         try {
  853.             //console.log("Image using OCR");
  854.             var urlString = qSelector(IMAGE_FOR_OCR).style.background;
  855.             var imageUrl = getUrlFromString(urlString);
  856.             if (imageUrl == 0) {
  857.                 return selectImagesAfterDelay(1);
  858.             }
  859.  
  860.             Jimp.read(imageUrl).then(function(data) {
  861.  
  862.                 data.getBase64(Jimp.AUTO, function(err, src) {
  863.  
  864.                     var img = document.createElement("img");
  865.                     img.setAttribute("src", src);
  866.                     var base64Image = img.src;
  867.  
  868.                     preProcessImage(base64Image, imageUrl);
  869.  
  870.                 })});
  871.  
  872.         } catch (err) {
  873.             console.log(err.message);
  874.             return selectImagesAfterDelay(1);
  875.         }
  876.     }
  877.  
  878.  
  879.     async function convertTextToImage(text) {
  880.  
  881.         //Convert Text to image
  882.         var canvas = document.createElement("canvas");
  883.         var textLength = text.length;
  884.         canvas.width = 60 * textLength;
  885.         canvas.height = 80;
  886.         var ctx = canvas.getContext('2d');
  887.         ctx.font = "30px Arial";
  888.         ctx.fillText(text, 10, 50);
  889.         var img = document.createElement("img");
  890.         img.src = canvas.toDataURL();
  891.  
  892.         return img;
  893.     }
  894.  
  895.     async function convertImageToText(img) {
  896.  
  897.         await initializeTesseractWorker();
  898.  
  899.         //Convert Image to Text
  900.         var text = "";
  901.         await worker.recognize(img, LANGUAGE_FOR_OCR).then(function(data) {
  902.             text = data.text;
  903.             // console.log("Recognized Text::" + text);
  904.         });
  905.         return text.trim();
  906.     }
  907.  
  908.     function areExampleImageUrlsChanged() {
  909.  
  910.         var prevExampleUrls = exampleImageList;
  911.         currentExampleUrls = [];
  912.  
  913.         if (qSelectorAll(CHALLENGE_IMAGE).length > 0) {
  914.             for (let i = 0; i < qSelectorAll(CHALLENGE_IMAGE).length; i++) {
  915.                 var urlString = qSelectorAll(CHALLENGE_IMAGE)[i].style.background;
  916.                 var imageUrl = getUrlFromString(urlString);
  917.                 if (imageUrl == 0) {
  918.                     console.log("Image url is empty, Retrying...");
  919.                     return true;
  920.                 }
  921.                 currentExampleUrls[i] = imageUrl;
  922.             }
  923.         }
  924.  
  925.         if (prevExampleUrls.length != currentExampleUrls.length) {
  926.             return true;
  927.         }
  928.  
  929.         for (let i = 0; i < currentExampleUrls.length; i++) {
  930.  
  931.             if (prevExampleUrls[i] != currentExampleUrls[i]) {
  932.                 return true;
  933.             }
  934.         }
  935.  
  936.         return false;
  937.     }
  938.  
  939.     async function identifyObjectsFromImages(imageUrlList) {
  940.         identifiedObjectsList = [];
  941.  
  942.         for (let i = 0; i < imageUrlList.length; i++) {
  943.             try {
  944.                 let img = new Image();
  945.                 img.crossOrigin = "Anonymous";
  946.                 img.src = imageUrlList[i];
  947.                 img.onload = () => {
  948.                     initializeTensorFlowModel().then(model => model.detect(img))
  949.                         .then(function(predictions) {
  950.                         let predictionslen = predictions.length;
  951.                         let hashSet = new Set();
  952.                         for (let j = 0; j < predictionslen; j++) {
  953.                             hashSet.add(predictions[j].class);
  954.                         }
  955.  
  956.                         hashSet.forEach((key) => {
  957.                             identifiedObjectsList.push(key);
  958.                         });
  959.  
  960.                         img.removeAttribute("src");
  961.  
  962.                         if (i == imageUrlList.length - 1) {
  963.                             identifyObjectsFromImagesCompleted = true;
  964.                         }
  965.  
  966.                     })
  967.                 }
  968.             } catch (e) {
  969.                 console.log(e);
  970.             }
  971.  
  972.         }
  973.  
  974.     }
  975.  
  976.     async function identifyObjectsFromImagesUsingMobileNet(imageUrlList) {
  977.         identifiedObjectsList = [];
  978.  
  979.         for (let i = 0; i < imageUrlList.length; i++) {
  980.             try {
  981.                 let img = new Image();
  982.                 img.crossOrigin = "Anonymous";
  983.                 img.src = imageUrlList[i];
  984.                 img.onload = () => {
  985.                     initializeTensorFlowMobilenetModel().then(model => model.classify(img))
  986.                         .then(function(predictions) {
  987.  
  988.                         let predictionslen = predictions.length;
  989.                         let hashSet = new Set();
  990.                         for (let j = 0; j < predictionslen; j++) {
  991.                             if(predictions[j].className.includes(",")){
  992.                                 var multiPredictions = predictions[j].className.split(',');
  993.                                 for(let k=0; k< multiPredictions.length;k++){
  994.                                     hashSet.add(multiPredictions[k].trim());
  995.                                 }
  996.                             }else{
  997.                                 hashSet.add(predictions[j].className);
  998.                             }
  999.                         }
  1000.  
  1001.                         hashSet.forEach((key) => {
  1002.                             identifiedObjectsList.push(key);
  1003.                         });
  1004.  
  1005.                         img.removeAttribute("src");
  1006.  
  1007.                         if (i == imageUrlList.length - 1) {
  1008.                             identifyObjectsFromImagesCompleted = true;
  1009.                         }
  1010.  
  1011.                     })
  1012.                 }
  1013.             } catch (e) {
  1014.                 console.log(e);
  1015.             }
  1016.  
  1017.         }
  1018.  
  1019.     }
  1020.  
  1021.     async function getWordFromIdentifiedObjects(identifiedObjectsList) {
  1022.  
  1023.         var hashMap = new Map();
  1024.         for (var i = 0; i < identifiedObjectsList.length; i++) {
  1025.             if (hashMap.has(identifiedObjectsList[i])) {
  1026.                 hashMap.set(identifiedObjectsList[i], hashMap.get(identifiedObjectsList[i]) + 1)
  1027.             } else {
  1028.                 hashMap.set(identifiedObjectsList[i], 1)
  1029.             }
  1030.         }
  1031.         var maxCount = 0,
  1032.             objectKey = -1;
  1033.         await hashMap.forEach((value, key) => {
  1034.             if (maxCount < value && (key.equalsOneOf(TRANSPORT_TYPES) ||
  1035.                                      key.equalsOneOf(LIVING_ROOM_TYPES) ||
  1036.                                      key.equalsOneOf(ANIMAL_TYPES)|| key == VALLEY)) {
  1037.                 objectKey = key;
  1038.                 maxCount = value;
  1039.             }
  1040.  
  1041.         });
  1042.  
  1043.         return objectKey;
  1044.     }
  1045.  
  1046.  
  1047.     function inputChallenge(data, imageUrl) {
  1048.         try {
  1049.             if ((qSelector(IMAGE_FOR_OCR).style.background).includes(imageUrl)) {
  1050.                 console.log(data.text);
  1051.                 var targetNode = qSelector(CHALLENGE_INPUT_FIELD);
  1052.                 targetNode.value = data.text.replaceAll("\n", "");
  1053.                 var challengeInput = qSelector(CHALLENGE_INPUT);
  1054.                 triggerEvent(challengeInput, 'input');
  1055.                 // Set a timeout if you want to see the text
  1056.                 qSelector(SUBMIT_BUTTON).click();
  1057.             }
  1058.  
  1059.         } catch (err) {
  1060.             console.log(err.message);
  1061.         }
  1062.     }
  1063.  
  1064.     async function identifyWordFromExamples() {
  1065.  
  1066.         var word = -1;
  1067.         if (areExampleImageUrlsChanged()) {
  1068.             exampleImageList = currentExampleUrls;
  1069.             if (exampleImageList.length == 0) {
  1070.                 return -1;
  1071.             }
  1072.             identifyObjectsFromImages(exampleImageList);
  1073.             while (!identifyObjectsFromImagesCompleted) {
  1074.                 await delay(2000)
  1075.             }
  1076.             identifyObjectsFromImagesCompleted = false;
  1077.             word = await getWordFromIdentifiedObjects(identifiedObjectsList);
  1078.  
  1079.             //Word has not been identified yet, use mobile net to recognize images
  1080.             if (word == -1) {
  1081.                 //Initialiaze MobileNet Model
  1082.                 await initializeTensorFlowMobilenetModel();
  1083.                 identifyObjectsFromImagesUsingMobileNet(exampleImageList);
  1084.                 while (!identifyObjectsFromImagesCompleted) {
  1085.                     await delay(2000)
  1086.                 }
  1087.                 identifyObjectsFromImagesCompleted = false;
  1088.  
  1089.                 word = getWordFromIdentifiedObjects(identifiedObjectsList);
  1090.             }
  1091.             return word;
  1092.  
  1093.         } else {
  1094.             return getWordFromIdentifiedObjects(identifiedObjectsList);
  1095.         }
  1096.  
  1097.         return word;
  1098.     }
  1099.  
  1100.     var prevObject = "";
  1101.  
  1102.     function isObjectChanged() {
  1103.         if (!prevObject && qSelector(PROMPT_TEXT)) {
  1104.             prevObject = qSelector(PROMPT_TEXT).innerText;
  1105.             return true;
  1106.         }
  1107.  
  1108.         if (prevObject && qSelector(PROMPT_TEXT) &&
  1109.             prevObject == qSelector(PROMPT_TEXT).innerText) {
  1110.             return false;
  1111.         }
  1112.  
  1113.         return true;
  1114.  
  1115.     }
  1116.  
  1117.  
  1118.     async function sanitizeWord(word){
  1119.         var chars =[];
  1120.         var alphabets = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";
  1121.         var answerChars = [];
  1122.         for(let i=0;i<word.length;i++){
  1123.             var tempCharImg = await convertTextToImage(word.charAt(i));
  1124.             for(let j=0;j< alphabets.length;j++){
  1125.                 var tempAlphabetImg = await convertTextToImage(alphabets.charAt(j));
  1126.                 if(tempCharImg.src == tempAlphabetImg.src){
  1127.                     answerChars[i] = alphabets[j];
  1128.                     break;
  1129.                 }
  1130.             }
  1131.         }
  1132.  
  1133.         word = answerChars.toString().replaceAll(",","");
  1134.         word = word.replaceAll(".","");
  1135.         return word;
  1136.  
  1137.     }
  1138.  
  1139.  
  1140.     async function identifyWord() {
  1141.         var word = -1;
  1142.         try {
  1143.             if (window.location.href.includes('&hl=en') || (ENABLE_DEFAULT_LANGUAGE && DEFAULT_LANGUAGE == LANG_ENGLISH)) {
  1144.                 word = qSelector(PROMPT_TEXT) ? qSelector(PROMPT_TEXT).innerText : word;
  1145.                 if (word && (word.includes(SENTENCE_TEXT_A) || word.includes(SENTENCE_TEXT_AN))) {
  1146.                     word = word.replace(SENTENCE_TEXT_A, '');
  1147.                     word = word.replace(SENTENCE_TEXT_AN, '');
  1148.                     word = word.replaceAll(".","");
  1149.                 }
  1150.  
  1151.                 if (word.equalsOneOf(TRANSPORT_TYPES) || word == VERTICAL_RIVER) {
  1152.                     return word;
  1153.                 } else {
  1154.                     //Using OCR on Text for accurate result
  1155.                     console.log("New word or different cyrillic");
  1156.  
  1157.                     word = await sanitizeWord(word);
  1158.                     console.log(word);
  1159.                     word = word.replace(SENTENCE_TEXT_A, '');
  1160.                     word = word.replace(SENTENCE_TEXT_AN, '');
  1161.                     word = word.replaceAll(".","");
  1162.                     if (word.equalsOneOf(TRANSPORT_TYPES) || word == VERTICAL_RIVER) {
  1163.                         return word;
  1164.                     } else {
  1165.                         if(MATCH_IMAGES_USING_TRAINER){
  1166.                             word = qSelector(PROMPT_TEXT) ? qSelector(PROMPT_TEXT).innerText : -1;
  1167.                             if(word){
  1168.                                 word = await sanitizeWord(word);
  1169.                                 word = word.replaceAll(".","");
  1170.                             }
  1171.                             return word;
  1172.                         }else{
  1173.                             word = await identifyWordFromExamples();
  1174.                         }
  1175.                     }
  1176.                 }
  1177.             } else {
  1178.  
  1179.                 //If word is not english
  1180.                 //Identify Images from Example
  1181.                 word = await identifyWordFromExamples();
  1182.             }
  1183.  
  1184.         } catch (e) {
  1185.             console.log(e);
  1186.         }
  1187.  
  1188.         return word;
  1189.     }
  1190.  
  1191.     var prevWord = "";
  1192.  
  1193.     async function selectImages() {
  1194.  
  1195.         if (ENABLE_DEFAULT_LANGUAGE) {
  1196.             for (let i = 0; i < qSelectorAll(LANGUAGE_SELECTOR).length; i++) {
  1197.                 if (qSelectorAll(LANGUAGE_SELECTOR)[i].innerText == DEFAULT_LANGUAGE) {
  1198.                     document.querySelectorAll(LANGUAGE_SELECTOR)[i].click();
  1199.                     await delay(1000);
  1200.                 }
  1201.             }
  1202.         }
  1203.  
  1204.         if (qSelectorAll(IMAGE) && qSelectorAll(IMAGE).length == 9 && qSelector(NO_SELECTION).getAttribute(ARIA_HIDDEN) != true) {
  1205.             await initializeTensorFlowMobilenetModel();
  1206.             selectedImageCount = 0;
  1207.             try {
  1208.  
  1209.                 if (isObjectChanged()) {
  1210.                     prevWord = await identifyWord();
  1211.                 }
  1212.  
  1213.                 var word = prevWord;
  1214.  
  1215.                 if (word == -1 && skipCount >= MAX_SKIPS) {
  1216.                     console.log("Max Retries Attempted. Captcha cannot be solved");
  1217.                     return;
  1218.                 } else if (word == -1 && skipCount < MAX_SKIPS) {
  1219.                     skipCount++;
  1220.                     if (qSelector(SUBMIT_BUTTON)) {
  1221.                         qSelector(SUBMIT_BUTTON).click();
  1222.                     }
  1223.                     return selectImagesAfterDelay(5);
  1224.                 } else {
  1225.                     //Get Synonyms for the word
  1226.                     word = await getSynonyms(word);
  1227.                     //console.log("words are::" + word);
  1228.                 }
  1229.  
  1230.  
  1231.             } catch (err) {
  1232.                 console.log(err.message);
  1233.                 return selectImagesAfterDelay(5);
  1234.             }
  1235.  
  1236.             var imageList = [];
  1237.             try {
  1238.                 imageList = getImageList();
  1239.                 if (imageList.length != 9) {
  1240.                     //console.log("Waiting");
  1241.                     // Image containers are visible but there are no urls in the image
  1242.                     // Skip the image
  1243.                     if (qSelector(SUBMIT_BUTTON)) {
  1244.                         qSelector(SUBMIT_BUTTON).click();
  1245.                     }
  1246.                     return selectImagesAfterDelay(5);
  1247.                 }
  1248.             } catch (err) {
  1249.                 console.log(err.message);
  1250.                 return selectImagesAfterDelay(5);
  1251.             }
  1252.  
  1253.             //Identifying word for seaplane and matching images
  1254.             //TODO: Refactor Code to combine different models or use only one model based on accuracy
  1255.             if(word && word != -1 && MATCH_IMAGES_USING_TRAINER && NEW_WORD_IDENTIFIED){
  1256.                 for (let i = 0; i < 9; i++) {
  1257.                     matchImagesUsingTrainer(imageList[i], word, i);
  1258.                 }
  1259.             }else if(word && word != -1 && USE_COLOUR_PATTERN){
  1260.                 for (let i = 0; i < 9; i++) {
  1261.                     matchImageForVerticalRiver(imageList[i], word, i);
  1262.                 }
  1263.             }else if (word && word != -1 && USE_MOBILE_NET) {
  1264.                 for (let i = 0; i < 9; i++) {
  1265.                     matchImagesUsingTensorFlowMobileNet(imageList[i], word, i);
  1266.                 }
  1267.             } else if (word && word != -1) {
  1268.                 for (var i = 0; i < 9; i++) {
  1269.                     if (ENABLE_TENSORFLOW) {
  1270.                         matchImagesUsingTensorFlow(imageList[i], word, i);
  1271.                     } else {
  1272.                         matchImages(imageList[i], word, i);
  1273.                     }
  1274.                 }
  1275.             }
  1276.             waitUntilImageSelection();
  1277.  
  1278.         } else {
  1279.             waitForImagesToAppear();
  1280.         }
  1281.     }
  1282.  
  1283.  
  1284. })();
Add Comment
Please, Sign In to add comment